package pessoal.funcionario;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import pessoal.Endereco;
import pessoal.Pessoa;
import pessoal.RepositorioPessoaBDR;
import pessoal.cliente.RepositorioClientesBDR;
import pessoal.funcionario.exception.FuncionarioExistenteException;
import pessoal.funcionario.exception.FuncionarioInvalidoException;
import util.CampoObrigatorioException;
import util.Conexao;
import util.ErroAcessoRepositorioException;

public class RepositorioFuncionariosBDR extends RepositorioPessoaBDR implements IRepositorioFuncionarios {
	
	
		
	private static final String UPDATE_FUNCIONARIO = "UPDATE func SET salario = ? " +
			" WHERE cpf_func = ?";
	
	
	private static final String INSERT_FUNCIONARIO="INSERT INTO func (cpf_func,salario) " +
			"VALUES (?,?)";
	
		
	private static final String CONSULTA_FUNCIONARIO = "SELECT * FROM pessoa INNER " +
			"JOIN func ON cpf = cpf_func WHERE cpf_func = ?";
	
	private static final String DELETE_FUNCIONARIO = "DELETE FROM func WHERE cpf_func = ?";
	
	private static final String CONSULTA_FUNCIONARIO_LISTAR = "SELECT * FROM pessoa INNER " +
	"JOIN func ON cpf = cpf_func";
	
	private static final String CONSULTA_FUNCIONARIO_EXISTE = "SELECT * FROM func " +
	"WHERE cpf_func = ?";
	
		
	
	public void atualizarFuncionario(Funcionario func)
			throws FuncionarioInvalidoException, ErroAcessoRepositorioException {
		Connection con = Conexao.getConexao();
		PreparedStatement pstmt = null;
		try {
			pstmt = con.prepareStatement(UPDATE_FUNCIONARIO);
			pstmt.setDouble(1, func.getSalario());
			pstmt.setString(2, func.getCpf());
			int rows = pstmt.executeUpdate();
			if (rows <= 0 ){
				throw new FuncionarioInvalidoException(func.getCpf());
 			}
			Endereco end = new Endereco (func.getEndereco().getRua(),func.getEndereco().getNumero(),func.getEndereco().getComplemento()
					,func.getEndereco().getBairro(),func.getEndereco().getCidade(),func.getEndereco().getCep(),func.getEndereco().getUf());
			
			Pessoa pessoa = new Pessoa(func.getNome(),func.getRg(),func.getCpf(),end);
			super.alterarPessoa(pessoa);
		} catch (SQLException e) {
			throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
					e,
					e.getErrorCode());
		} finally{
			Conexao.fechaRecursos(con,pstmt,null);
		}

	}

	
	public Funcionario consultarFuncionario(String cpf)
			throws FuncionarioInvalidoException, ErroAcessoRepositorioException {
		Funcionario func = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		con = Conexao.getConexao();
		try {
			pstmt=con.prepareStatement(CONSULTA_FUNCIONARIO);
			pstmt.setString(1, cpf);
			rs=pstmt.executeQuery();
			if(rs.next()){
				String nome = rs.getString("nome");
				String rg = rs.getString("rg");
				double salario = rs.getDouble("salario");
				String rua = rs.getString("rua");
				String numero = rs.getString("numero");
				String complemento = rs.getString("complemento");
				String bairro = rs.getString("bairro");
				String cidade = rs.getString("cidade");
				String cep = rs.getString("cep");
				String uf = rs.getString("uf");
				func = 
					new Funcionario(cpf,nome,rg,new Endereco(rua,numero,complemento,bairro,cidade,cep,uf),salario);
			}else{
				throw new FuncionarioInvalidoException(cpf);
			}
		} catch (SQLException e) {
			throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
					e,
					e.getErrorCode());
		}finally{
			Conexao.fechaRecursos(con,pstmt,rs);
		}
		return func;
	}

	/*O excluir exclui de funcionario mas nao exclui de pessoa caso esse 
	 * funcionario tb seja um cliente. se esse funcionario nao for tb
	 * cliente ele exclui das duas.
	 *  
	 * */
	public void excluirFuncionario(String cpf)
			throws FuncionarioInvalidoException, ErroAcessoRepositorioException {
		PreparedStatement pstmt = null;
		Connection con = null;
		if(existeFuncionario(cpf)){
			try {
				con = Conexao.getConexao();
				pstmt = con.prepareStatement(DELETE_FUNCIONARIO);
				pstmt.setString(1, cpf);
				pstmt.executeUpdate();
				RepositorioClientesBDR repClientes = new RepositorioClientesBDR();
				if(!repClientes.existeCliente(cpf)){
					super.excluirPessoa(cpf);
				}
			} catch (SQLException e) {
				throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
						e,
						e.getErrorCode());
			}finally{
				Conexao.fechaRecursos(con,pstmt,null);
			}
		}else{
			throw new FuncionarioInvalidoException(cpf);
		}

	}

	public boolean existeFuncionario(String cpf) throws ErroAcessoRepositorioException {
		Connection con = null;
		PreparedStatement pstmt = null;
		con = Conexao.getConexao();
		ResultSet rs = null;
		try {
			pstmt=con.prepareStatement(CONSULTA_FUNCIONARIO_EXISTE);
			pstmt.setString(1, cpf);
			rs = pstmt.executeQuery();
			if(rs.next()){
				String qtdLinhas = rs.getString("cpf_func");
				return (qtdLinhas != null);
			}
		} catch (SQLException e) {
			throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
					e,
					e.getErrorCode());
		}finally{
			Conexao.fechaRecursos(con,pstmt,rs);
		}
		
		return false;
	}
	
	

	/*
	 * Insere em pessoa e depois insere em funcionario
	 * 
	 */
	public void inserirFuncionario(Funcionario func)
			throws FuncionarioExistenteException,
			ErroAcessoRepositorioException, CampoObrigatorioException {
		Endereco end = new Endereco (func.getEndereco().getRua(),func.getEndereco().getNumero(),func.getEndereco().getComplemento()
				,func.getEndereco().getBairro(),func.getEndereco().getCidade(),func.getEndereco().getCep(),func.getEndereco().getUf());
		
		Pessoa pessoa = new Pessoa(func.getNome(),func.getRg(),func.getCpf(),end);
		if(func.getCpf()!=null && func.getCpf()!="" && func.getNome()!=null
				&& func.getNome()!="" &&func.getRg()!=null 
				&& func.getRg()!=""){
			Connection con = null;
			PreparedStatement pstmt = null;
			try {
				super.inserePessoa(pessoa);
				if(!existeFuncionario(func.getCpf())){
					con = Conexao.getConexao();
					pstmt=con.prepareStatement(INSERT_FUNCIONARIO);
					pstmt.setString(1, func.getCpf());
					pstmt.setDouble(2, func.getSalario());
					pstmt.executeUpdate();
				}else{
					throw new FuncionarioExistenteException(func.getCpf());
				}
			} catch (SQLException e) {
				throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
						e,
						e.getErrorCode());
			}finally{
				Conexao.fechaRecursos(con,pstmt,null);
			}
		}else{
			throw new CampoObrigatorioException("CPF, Nome e RG.");
		}
	}

	
	public List<Funcionario> listarFuncionarios()
			throws ErroAcessoRepositorioException {
		PreparedStatement pstmt = null;
		Connection con = null;
		ResultSet rs = null;
		ArrayList<Funcionario> funcionarios = new ArrayList<Funcionario>();
		con = Conexao.getConexao();
		try {
			pstmt = con.prepareStatement(CONSULTA_FUNCIONARIO_LISTAR);
			rs = pstmt.executeQuery();
			while(rs.next()){
				String cpf = rs.getString("cpf");
				String nome = rs.getString("nome");
				String rg = rs.getString("rg");
				double salario = rs.getDouble("salario");
				String rua = rs.getString("rua");
				String numero = rs.getString("numero");
				String complemento = rs.getString("complemento");
				String bairro = rs.getString("bairro");
				String cidade = rs.getString("cidade");
				String cep = rs.getString("cep");
				String uf = rs.getString("uf");
				Endereco end = 
					new Endereco(rua,numero,complemento,bairro,cidade,cep,uf);
				Funcionario func = 
					new Funcionario(cpf,nome,rg,end,salario);
				funcionarios.add(func);
			}
		} catch (SQLException e) {
			throw new ErroAcessoRepositorioException(MSG_ERRO_ACESSO_BD,
					e,
					e.getErrorCode());
		}finally{
			Conexao.fechaRecursos(con,pstmt,rs);
		}
		return funcionarios;
	}



}
